package com.hontlong.commons.threadpool;

import java.util.Collection;
import java.util.Iterator;
import java.util.Vector;

/**
 * 线程池
 * 
 * @author ryang 2006-8-8
 */
public class ThreadPool {

	private int maxPoolSize;

	private int initPoolSize;

	private Vector<PooledThread> threads = new Vector<PooledThread>();

	private boolean initialized;

	private boolean hasIdleThread;

	public ThreadPool(final int maxPoolSize, final int initPoolSize) {
		this.maxPoolSize = maxPoolSize;
		this.initPoolSize = initPoolSize;
		this.init();
	}

	public synchronized PooledThread getIdleThread() {
		while (true) {
			for (final PooledThread th : this.threads) {
				if (!th.isRunning()) {// TODO 这里有同步问题
					return th;
				}
			}

			if (this.getPoolSize() < this.maxPoolSize) {
				final PooledThread thread = new PooledThread(this);
				thread.start();
				this.threads.add(thread);
				return thread;
			}
			this.hasIdleThread = false;
			if (this.waitForIdleThread() == false) {
				return null;
			}
		}
	}

	public synchronized int getPoolSize() {
		return this.threads.size();
	}

	private void init() {
		this.initialized = true;
		for (int i = 0; i < this.initPoolSize; i++) {
			final PooledThread thread = new PooledThread(this);
			thread.start();
			this.threads.add(thread);
		}
	}

	protected void notifyForIdleThread() {
		this.hasIdleThread = true;
	}

	public void processTask(final Runnable task) {
		final PooledThread th = this.getIdleThread();
		if (th != null) {
			th.putTask(task);
			th.startTasks();
		}
	}

	public void processTasksInSingleThread(final Collection<Runnable> tasks) {
		final PooledThread th = this.getIdleThread();
		if (th != null) {
			th.putTasks(tasks);
			th.startTasks();
		}
	}

	public void processTasksInSingleThread(final Runnable[] tasks) {
		final PooledThread th = this.getIdleThread();
		if (th != null) {
			th.putTasks(tasks);
			th.startTasks();
		}
	}

	public synchronized void setMaxPoolSize(final int maxPoolSize) {
		// System.out.println("重设最大线程数，最大线程数=" + maxPoolSize);
		this.maxPoolSize = maxPoolSize;
		if (maxPoolSize < this.getPoolSize()) {
			this.setPoolSize(maxPoolSize);
		}
	}

	/**
	 * 重设当前线程数 若需杀掉某线程，线程不会立刻杀掉，而会等到线程中的事务处理完成 但此方法会立刻从线程池中移除该线程，不会等待事务处理结束
	 * 
	 * @param size
	 */
	public synchronized void setPoolSize(final int size) {
		if (!this.initialized) {
			this.initPoolSize = size;
			return;
		} else if (size > this.getPoolSize()) {
			for (int i = this.getPoolSize(); (i < size)
					&& (i < this.maxPoolSize); i++) {
				final PooledThread thread = new PooledThread(this);
				thread.start();
				this.threads.add(thread);
			}
		} else if (size < this.getPoolSize()) {
			while (this.getPoolSize() > size) {
				final PooledThread th = this.threads.remove(0);
				th.kill();
			}
		}
	}

	/**
	 * 
	 */
	public synchronized void stopIdleThread() {
		for (final Iterator<PooledThread> it = this.threads.iterator(); it
				.hasNext();) {
			final PooledThread t = it.next();
			if (!t.isRunning()) {
				t.kill();
				it.remove();
			}
		}
	}

	protected boolean waitForIdleThread() {
		while (!this.hasIdleThread && (this.getPoolSize() >= this.maxPoolSize)) {
			try {
				Thread.sleep(5);
			} catch (final InterruptedException e) {
				return false;
			}
		}
		return true;
	}
}
